#include "Dwarf.Unmanaged.Omp.h"

//Pointers to the factory functions.
static DLLParseArguments pDLLParseArguments;
static DLLUsage pDLLUsage;
static DLLStart pDLLStart;
static DLLStop pDLLStop;

//Pointers to dll.
static HINSTANCE hInstDll;

// Constructor that init strings.
Settings :: Settings()
{
    inputFile = new char[BUFFER_SIZE];
    resultFile = new char[BUFFER_SIZE];
	profileFile = new char[BUFFER_SIZE];

    inputFile[0] = resultFile[0] = profileFile[0] ='\0';
}

// Constructor that dispose strings.
Settings :: ~Settings()
{
    delete inputFile;
    delete resultFile;
	delete profileFile;
}


// Parse input file into solver's structures.
int Settings::parseConfigFile(Solver* clsolver) 
{
    // Open the file to read from.
    if( fopen_s(&clsolver->input, inputFile, "rb")) 
    {
        printf("Can't open configfile!\r\n");
        (pDLLUsage)();

        return -1;
    }

    //Get length of file.
    fseek(clsolver->input, 0, SEEK_END );
    clsolver->length = ftell(clsolver->input);
    rewind(clsolver->input);    

    return 0;
}

// Init variables, parse cli params and input file.
int Settings::init(int argc, char** argv, Solver *clsolver) 
{
    
    // Load the dll into the address space
    hInstDll = LoadLibraryA("CliTools");
    if (!(hInstDll)) 
    {
        printf("Error while loading CliTools.dll.");
        return -1;
    }

    // Retrieve a pointer to the factory function
    pDLLParseArguments = 
        (DLLParseArguments) GetProcAddress(hInstDll, "parseArguments");

    pDLLUsage =
        (DLLUsage) GetProcAddress(hInstDll, "usage");

    pDLLStart = 
        (DLLStart) GetProcAddress(hInstDll, "start");

    pDLLStop = 
        (DLLStop) GetProcAddress(hInstDll, "stop");

    //Parse cli params.
    if ((pDLLParseArguments)(argc, argv, &inputFile, &profileFile,  &resultFile)) 
    {
        FreeLibrary(hInstDll); 
        return -1;
    }

    //Parse input file.    
    if (parseConfigFile(clsolver)) 
    {
        FreeLibrary(hInstDll); 
        return -1;
    }

    //Write settings if it's needed.
    writeSettings(clsolver);	
    return 0;
}

// Start the time count.
void Settings::start() 
{
    (pDLLStart)();
}

// Problem results output.
void Settings::finish(Solver *clsolver)
{
    double time;
    (pDLLStop)(&time);

    //Release dll.
    FreeLibrary(hInstDll);

    printf("\r\n");
    printf("Clock time (sec): %.8f \r\n", time);  

    FILE* outputResult = 0;
    FILE* outputProfile = 0;

    if( fopen_s(&outputProfile, profileFile , "wb")) 
    {
        printf("Can't create profile file!\r\n");            
		fclose(outputProfile);
        return;
    }

    if( fopen_s(&outputResult, resultFile , "wb")) 
    {
        printf("Can't create result file!\r\n");   
        fclose(outputResult);
        return;
    }
   
    
    fprintf(outputProfile, "#Dwarfname:%s\r\n",DWARF_NAME);

    char tmpbuf[BUFFER_SIZE];
    _tzset();
    
    _strdate_s( tmpbuf, BUFFER_SIZE );
    fprintf(outputProfile, "#Time: %s ",tmpbuf);

    _strtime_s( tmpbuf, BUFFER_SIZE );
    fprintf(outputProfile, "%s \r\n",tmpbuf);

    fprintf(outputProfile, "#Result time (sec): %.8f\r\n", time);
    fprintf(outputProfile, "#File length (byte) : %lu \r\n", clsolver->length);
    fprintf(outputProfile, "#Result count: %lu\r\n", clsolver->resultCount);
    fprintf(outputResult, "#Result count: %lu\r\n", clsolver->resultCount);
    fprintf(outputProfile, "#eof");

    fclose(outputProfile);
    fclose(outputResult);

}

// Write settings.
void Settings::writeSettings(Solver *clsolver)
{
    // Write general settings.
    printf("Kernel settings summary : \r\n");
	printf("Dwarf name              : %s \r\n", DWARF_NAME);
    printf("File length (byte)      : %lu \r\n", clsolver->length);
	printf("Input file              : %s \r\n", inputFile);
	printf("Profile file            : %s \r\n", profileFile);    
	printf("Result file             : %s \r\n", resultFile);    
    printf("\r\n");

}